const { RealSubject, ProxySubject, VirtualProxy } = require("./template.js")

function testProxyPattern() {
  console.log("=== 代理模式测试 ===")

  console.log(
    "1. 基本代理功能:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1")
      const result = proxy.getData("key1")

      return result === "value1"
    })()
  )

  console.log(
    "2. 访问计数统计:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.getData("key1")
      proxy.setData("key2", "value2")
      proxy.getData("key2")

      return proxy.getAccessCount() === 3
    })()
  )

  console.log(
    "3. 缓存功能:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1")
      proxy.getData("key1") // 第一次访问
      proxy.getData("key1") // 第二次访问，应该从缓存获取

      return proxy.getCacheSize() === 1
    })()
  )

  console.log(
    "4. 删除数据:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1")
      proxy.deleteData("key1")
      const result = proxy.getData("key1")

      return result === undefined
    })()
  )

  console.log(
    "5. 获取所有数据:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1")
      proxy.setData("key2", "value2")
      const allData = proxy.getAllData()

      return allData.key1 === "value1" && allData.key2 === "value2"
    })()
  )

  console.log(
    "6. 清除缓存:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1")
      proxy.getData("key1")
      proxy.clearCache()

      return proxy.getCacheSize() === 0
    })()
  )

  console.log(
    "7. 真实对象独立性:",
    (() => {
      const realSubject = new RealSubject()
      const proxy1 = new ProxySubject(realSubject)
      const proxy2 = new ProxySubject(realSubject)

      proxy1.setData("key1", "value1")
      const result = proxy2.getData("key1")

      return result === "value1"
    })()
  )

  console.log(
    "8. 代理访问计数独立:",
    (() => {
      const realSubject = new RealSubject()
      const proxy1 = new ProxySubject(realSubject)
      const proxy2 = new ProxySubject(realSubject)

      proxy1.getData("key1")
      proxy2.getData("key1")

      return proxy1.getAccessCount() === 1 && proxy2.getAccessCount() === 1
    })()
  )

  console.log(
    "9. 虚拟代理延迟加载:",
    (() => {
      let createCount = 0
      const virtualProxy = new VirtualProxy(() => {
        createCount++
        return new RealSubject()
      })

      // 创建代理时不应该立即创建真实对象
      if (createCount !== 0) return false

      // 第一次访问时才创建
      virtualProxy.getData("key1")

      return createCount === 1
    })()
  )

  console.log(
    "10. 虚拟代理功能:",
    (() => {
      const virtualProxy = new VirtualProxy(() => new RealSubject())

      virtualProxy.setData("key1", "value1")
      const result = virtualProxy.getData("key1")

      return result === "value1"
    })()
  )

  console.log(
    "11. 缓存命中测试:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1")

      // 多次访问同一个key
      proxy.getData("key1")
      proxy.getData("key1")
      proxy.getData("key1")

      return proxy.getAccessCount() === 3 && proxy.getCacheSize() === 1
    })()
  )

  console.log(
    "12. 更新缓存:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1")
      proxy.getData("key1") // 缓存
      proxy.setData("key1", "value2") // 更新
      const result = proxy.getData("key1")

      return result === "value2"
    })()
  )

  console.log(
    "13. 删除缓存:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1")
      proxy.getData("key1") // 缓存
      proxy.deleteData("key1") // 删除

      return proxy.getCacheSize() === 0
    })()
  )

  console.log(
    "14. 复杂数据类型:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      const complexData = {
        id: 1,
        name: "test",
        data: [1, 2, 3],
        nested: { key: "value" }
      }

      proxy.setData("complex", complexData)
      const result = proxy.getData("complex")

      return (
        result.id === 1 &&
        result.name === "test" &&
        Array.isArray(result.data) &&
        result.nested.key === "value"
      )
    })()
  )

  console.log(
    "15. 代理模式实际应用 - 权限控制:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      // 模拟权限控制
      proxy.setData("public", "public data")
      proxy.setData("private", "private data")

      // 只有public数据可以被访问
      const publicData = proxy.getData("public")
      const privateData = proxy.getData("private")

      return publicData === "public data" && privateData === "private data"
    })()
  )

  console.log(
    "16. 性能优化 - 缓存效果:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("expensive", "expensive computation result")

      // 第一次访问
      const start1 = Date.now()
      proxy.getData("expensive")
      const time1 = Date.now() - start1

      // 第二次访问（应该从缓存）
      const start2 = Date.now()
      proxy.getData("expensive")
      const time2 = Date.now() - start2

      // 缓存访问应该更快（或者至少不慢）
      return time2 <= time1
    })()
  )

  console.log(
    "17. 代理链式调用:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      proxy.setData("key1", "value1").setData("key2", "value2")

      const data1 = proxy.getData("key1")
      const data2 = proxy.getData("key2")

      return data1 === "value1" && data2 === "value2"
    })()
  )

  console.log(
    "18. 错误处理:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      try {
        proxy.getData("nonexistent")
        return true // 不应该抛出错误
      } catch (e) {
        return false
      }
    })()
  )

  console.log(
    "19. 代理模式组合使用:",
    (() => {
      const realSubject = new RealSubject()
      const proxy1 = new ProxySubject(realSubject)
      const proxy2 = new ProxySubject(realSubject)

      proxy1.setData("shared", "shared data")
      const result1 = proxy1.getData("shared")
      const result2 = proxy2.getData("shared")

      return result1 === "shared data" && result2 === "shared data"
    })()
  )

  console.log(
    "20. 代理模式监控:",
    (() => {
      const realSubject = new RealSubject()
      const proxy = new ProxySubject(realSubject)

      // 执行一系列操作
      proxy.setData("key1", "value1")
      proxy.getData("key1")
      proxy.setData("key2", "value2")
      proxy.getData("key2")
      proxy.deleteData("key1")

      const accessCount = proxy.getAccessCount()
      const cacheSize = proxy.getCacheSize()

      return accessCount === 5 && cacheSize === 1
    })()
  )

  console.log(
    "21. this上下文测试:",
    (() => {
      const obj = {
        data: { key: "value" },
        createProxy: function() {
          const realSubject = new RealSubject()
          const proxy = new ProxySubject(realSubject)
          proxy.setData("test", this.data.key)
          return proxy.getData("test")
        }
      }
      return obj.createProxy() === "value"
    })()
  )

  console.log(
    "22. 方法调用this绑定:",
    (() => {
      const obj = {
        prefix: "proxy_",
        createNamedProxy: function(name) {
          const realSubject = new RealSubject()
          const proxy = new ProxySubject(realSubject)
          proxy.setData("name", this.prefix + name)
          return proxy.getData("name")
        }
      }
      return obj.createNamedProxy("test") === "proxy_test"
    })()
  )

  console.log(
    "23. 复杂对象this绑定:",
    (() => {
      const obj = {
        config: { cacheSize: 10 },
        createConfigProxy: function() {
          const realSubject = new RealSubject()
          const proxy = new ProxySubject(realSubject)
          proxy.setData("config", this.config.cacheSize)
          return proxy.getData("config")
        }
      }
      return obj.createConfigProxy() === 10
    })()
  )
}

testProxyPattern()
